package ip

import (
	"fmt"
	"math/big"
	"net"
)

// CIDRToIPRange 根据CIDR表示的子网范围生成所有IP地址
func CIDRToIPRange(cidr string) ([]net.IP, error) {
	ip, ipnet, err := net.ParseCIDR(cidr)
	if err != nil {
		return nil, err
	}
	if ip.To4() == nil {
		return nil, fmt.Errorf("只支持IPv4 CIDR")
	}
	ones, bits := ipnet.Mask.Size()
	if bits != 32 {
		return nil, fmt.Errorf("只支持IPv4掩码")
	}
	if ones < 0 || ones > 32 {
		return nil, fmt.Errorf("掩码位数无效")
	}
	count := 1 << (32 - ones)
	if count > 4096 {
		return nil, fmt.Errorf("子网过大，最多支持4096个IP")
	}
	var ips []net.IP
	ipInt := big.NewInt(0).SetBytes(ip.To4())
	for i := 0; i < count; i++ {
		b := make([]byte, 4)
		big.NewInt(0).Add(ipInt, big.NewInt(int64(i))).FillBytes(b)
		ips = append(ips, net.IPv4(b[0], b[1], b[2], b[3]))
	}
	return ips, nil
}

// IPsInSubnet 根据IP地址和子网掩码生成所有IP地址
func IPsInSubnet(baseIP, subnetMask string) ([]net.IP, error) {
	ip := net.ParseIP(baseIP)
	mask := net.ParseIP(subnetMask)
	if ip == nil || mask == nil {
		return nil, fmt.Errorf("IP或掩码格式错误")
	}
	mask4 := mask.To4()
	if mask4 == nil {
		return nil, fmt.Errorf("只支持IPv4掩码")
	}
	maskInt := net.IPv4Mask(mask4[0], mask4[1], mask4[2], mask4[3])
	ipnet := &net.IPNet{IP: ip.Mask(maskInt), Mask: maskInt}
	return CIDRToIPRange(ipnet.String())
}

// PrintIPRange 打印指定CIDR范围内的所有IP地址
func PrintIPRange(cidr string) error {
	ips, err := CIDRToIPRange(cidr)
	if err != nil {
		return err
	}
	for i, ip := range ips {
		fmt.Printf("IP #%d: %s\n", i+1, ip.String())
	}
	return nil
}
